<?php

// -----------------------------------------------------------------------------
// generate a zip file on the fly and download it
function generate_interim_file($project, $limit_round_id, $which_text, $include_proofers)
{
    global $dpdb;
    $projectid = $project->ProjectId();

    if ('[OCR]' == $limit_round_id) 
    {
        $filename = "{$projectid}_OCR";
    }
    else
    {
        $filename = "{$projectid}_{$limit_round_id}";
        $filename .= $which_text == "EQ" ? '_saved' : '_latest';
    }

    $sql = page_info_sql($project, $limit_round_id, $which_text);
    $page_rows = $dpdb->SqlRows( $sql );
    // join the page texts together
    $filedata = join_proofed_text($project, $page_rows, $include_proofers );

    // zip it all up

    // first find a unique place to operate in:
    $dirname = "/tmp/".uniqid("post_files");
    mkdir($dirname, 0777);      // and make the directory

    $textfile_path = "{$dirname}/{$filename}.txt";

    // make sure that everything will be cleaned up on exit
    register_shutdown_function("clean_up_temp", $dirname, $textfile_path);

    // now write the text file
    file_put_contents($textfile_path, $filedata);
    // $handle = fopen($textfile_path,"w");
    // fwrite($handle,$filedata);
    // fclose($handle);
    // make the zip and sent it to the user
    header("Content-type: application/octet-stream");   
    header("Content-disposition: attachment; filename={$filename}.zip");   
    passthru("zip -q -j - $textfile_path", $return_code);
    if ($return_code != 0)
    {
        echo "post_files: the zip command failed.";
    }
    // cleanup will get called whatever happens  
}

function clean_up_temp($dirname, $textfile_path) 
{
    // now we must clean up behind ourselves
    unlink($textfile_path);
    rmdir($dirname);
}


function join_page_texts( $page_rows )
// Return the concatenation of the page-texts in the query-result.
// (Similar to join_proofed_text, but without the page-separators.)
{
    $text = "";
    foreach($rows as $row)
        $text .= $row['pagetext'];
    }
    return $text;
}

// -----------------------------------------------------------------------------

function join_proofed_text ($project, $page_rows, $include_proofers)
{
    $filedata = "";
    foreach($page_rows as $row)
    {
        $info_str = "-----File: {$row['fileid']}---";
        if ($include_proofers) {
            $info_str .= "\\{$row['pageuser']}\\";
        }
        
        $separator_line = str_pad( $info_str, 74, '-', STR_PAD_RIGHT ) . '-';
        $fileinfo = "\n{$separator_line}\n{$row['pagetext']}";
            $filedata .= $fileinfo;
    }
    return $filedata;
}

// -----------------------------------------------------------------------------

$carriagereturn = chr(13);   
$linefeed = chr(10);

function join_proofed_text_tei ($project, $pages_res, $include_proofers, $fp)
{
    global $code_url, $projects_url, $charset;
   
    $result = mysql_query("SELECT nameofwork, authorsname, language, postednum FROM projects WHERE projectid = '$project'");
    $row = mysql_fetch_row($result);

    $nameofwork  = $row[0];
    $authorsname = $row[1];
    $language    = $row[2];
    $postednum   = $row[3];

    fputs($fp,"<?xml version=\"1.0\" encoding=\"$charset\" ?>\r\n");
    fputs($fp,"<!DOCTYPE TEI.2 SYSTEM \"http://www.gutenberg.org/tei/marcello/0.4/dtd/pgtei.dtd\">");
    fputs($fp,"\r\n");
    fputs($fp,"<TEI.2 lang=\"en\">\r\n");
    // Dump the teiHeader.
    // The info for this might preferably come from
    // a database of MARC records.
    fputs($fp,"    <teiHeader>\r\n");
    fputs($fp,"        <fileDesc>\r\n");
    fputs($fp,"            <titleStmt>\r\n");
    fputs($fp,"                <title>$nameofwork</title>\r\n");
    fputs($fp,"                <author>$authorsname</author>\r\n");
    fputs($fp,"            </titleStmt>\r\n");
    fputs($fp,"            <publicationStmt>\r\n");
    fputs($fp,"                <publisher>Project Gutenberg</publisher>\r\n");
    fputs($fp,"                <pubPlace>Urbana</pubPlace>\r\n");
    fputs($fp,"                <date>20XX</date>\r\n");
    fputs($fp,"                <idno type='etext-no'>99999</idno>\r\n");
    fputs($fp,"                <availability>\r\n");
    fputs($fp,"                  <p>This eBook is for the use of anyone anywhere\r\n");
    fputs($fp,"                  at no cost and with almost no restrictions whatsoever.\r\n");
    fputs($fp,"                  You may copy it, give it away or re-use it under\r\n");
    fputs($fp,"                  the terms of the Project Gutenberg License online at\r\n");
    fputs($fp,"                  www.gutenberg.org/license</p>\r\n");
    fputs($fp,"                </availability>\r\n");
    fputs($fp,"            </publicationStmt>\r\n");
    fputs($fp,"            <sourceDesc>\r\n");
    fputs($fp,"                <p></p>\r\n");
    fputs($fp,"            </sourceDesc>\r\n");
    fputs($fp,"        </fileDesc>\r\n");
    fputs($fp,"        <encodingDesc>\r\n");
    fputs($fp,"        </encodingDesc>\r\n");
    fputs($fp,"        <profileDesc>\r\n");
    fputs($fp,"          <langUsage>\r\n");
    fputs($fp,"            <language id=\"it\" />\r\n");
    fputs($fp,"            <language id=\"fr\" />\r\n");
    fputs($fp,"            <language id=\"en\" />\r\n");
    fputs($fp,"            <language id=\"de\" />\r\n");
    fputs($fp,"          </langUsage>\r\n");
    fputs($fp,"        </profileDesc>\r\n");
    fputs($fp,"        <revisionDesc>\r\n");
    fputs($fp,"          <change>\r\n");
    fputs($fp,"            <date value=\"200X-XX\">October 200X</date>\r\n");
    fputs($fp,"            <respStmt>\r\n");
    fputs($fp,"                <resp>Produced by <name>[project manager]</name>, <name>[post-processor]</name>, <name>[scanner?]</name>,\r\n");
    fputs($fp,"                and the <name>Online Distributed Proofreading Team</name> at\r\n");
    fputs($fp,"                &lt;$code_url&gt;.\r\n");
    fputs($fp,"                Page-images available at\r\n");
    fputs($fp,"                &lt;$projects_url/$project/&gt;</resp>\r\n");
    fputs($fp,"            </respStmt>\r\n");
    fputs($fp,"            <item>Project Gutenberg TEI edition 1</item>\r\n");
    fputs($fp,"          </change>\r\n");
    fputs($fp,"        </revisionDesc>\r\n");
    fputs($fp,"    </teiHeader>\r\n");
    fputs($fp,"\r\n");
    fputs($fp,"    <pgExtensions>\r\n");
    fputs($fp,"      <pgStyleSheet>\r\n");
    fputs($fp,"        .bold        { font-weight: bold }\r\n");
    fputs($fp,"        .italic      { font-style: italic }\r\n");
    fputs($fp,"        .antiqua     { font-weight: bold }\r\n");
    fputs($fp,"        .gesperrt    { font-style: italic }\r\n");
    fputs($fp,"        .smallcaps   { font-variant: small-caps }\r\n");
    fputs($fp,"      </pgStyleSheet>\r\n");
    fputs($fp,"    </pgExtensions>\r\n");
    fputs($fp,"\r\n");
    fputs($fp,"<text>\r\n");
    fputs($fp,"<front>\r\n");
    fputs($fp,"</front>\r\n");
    fputs($fp,"<body>\r\n");

    while( list($text_data,$filename,$proofer_names) = page_info_fetch($pages_res) )
    {
        $pageno = eregi_replace ("\..*", "", $filename );
        fputs($fp,"\r\n\r\n<pb n='$pageno'/><anchor id='Pg$pageno'/>\r\n\r\n");
        // SENDING PAGE-TEXT TO USER
        // It's an XML file, so the non-markup angle-brackets and ampersands
        // should be entity-encoded, but it's tricky to find them.
        put_page_text($text_data, $fp);
    } //end else

    fputs($fp,"        </body>\r\n");
    fputs($fp,"        <back>\r\n");
    fputs($fp,"        </back>\r\n");
    fputs($fp,"    </text>\r\n");
    fputs($fp,"</TEI.2>\r\n");
}

function put_page_text( $page_text, $fp )
{
    // global \r\n;

    $page_text = eregi_replace( "<i>", "<hi rend='italic'>", $page_text );
    $page_text = eregi_replace( "</i>", "</hi>", $page_text );
    $page_text = eregi_replace( "<b>", "<hi rend='bold'>", $page_text );
    $page_text = eregi_replace( "</b>", "</hi>", $page_text );
    $page_text = eregi_replace( "<f>", "<hi rend='antiqua'>", $page_text );
    $page_text = eregi_replace( "</f>", "</hi>", $page_text );
    $page_text = eregi_replace( "<g>", "<hi rend='gesperrt'>", $page_text );
    $page_text = eregi_replace( "</g>", "</hi>", $page_text );
    $page_text = eregi_replace( "<sc>", "<hi rend='smallcaps'>", $page_text );
    $page_text = eregi_replace( "</sc>", "</hi>", $page_text );

    // Convert [Illustration...] blocks, and ensure that each
    // constitutes a separate "chunk".
    $page_text = preg_replace(
        "/\[Illustration: ([^\]]*)\]/",
        "\r\n\r\n<pgIf output='txt'><then>\r\n  <p>[Illustration: \\1]</p>\r\n</then><else>\r\n  <p><figure><head>\\1</head></figure></p>\r\n</else></pgIf>\r\n\r\n",
        $page_text );

    // Ditto [Footnote: ] blocks.
    $page_text = preg_replace(
        "/\[Footnote[^:]: ([^\]]*)\]/",
        "\r\n\r\n<note place='foot'>\\1</note>\r\n\r\n",
        $page_text );

    // Ampersands as entities
    $page_text = preg_replace( "/&([^\s;]*\s)/", "&amp;\\1", $page_text );

    // remove  [Blank Page]
    $page_text = preg_replace( "/\[Blank Page\]/", "", $page_text );

    // Ditto preformatted blocks.
    $page_text = preg_replace_callback(
        ';/\*(.*?)\*/;s', 'massage_preformatted_chunk',
        $page_text );

    // Remove whitespace (including EOLs) at the start or end of the page.
    $page_text = trim( $page_text );



    // Now split the content of the page on sequences of 2 or more EOLs
    // (i.e., sequences of 1 or more blank lines)
    
    // old line, split every character
    $chunks = preg_split( "/\r\n(\r\n)+/", $page_text );
    // $chunks = preg_split( "/\n\n+/", $page_text );
    // The only remaining EOLs must be singles, embedded within chunks.

    // Handle each chunk:
    for ( $i = 0; $i < count($chunks); $i++ )
    {
        $chunk = $chunks[$i];

        // Separate chunks with a blank line.
        if ( $i > 0 )
        {
            fputs($fp, "\r\n");
        }

        if ( startswith( $chunk, '<pgIf' ) || startswith( $chunk, '<lg>' ) || startswith( $chunk, '<note' ))
        {
            fputs($fp, "$chunk\r\n");
        }
        else
        {
            fputs($fp, "<p>\r\n$chunk\r\n</p>\r\n");
        }
    }
}

function massage_preformatted_chunk($matches)
// Handle a chunk of preformatted text.
// $matches[0] is the whole chunk, including delimiters.
// $matches[1] is the body of the chunk, between the delimiters.
{
    // global \r\n;

    $s = $matches[1];

    // On each line with non-blank content,
    // embed that content in an <l> element.
    // replace indentation with an attribute-value pair

    $s = preg_replace_callback(
        '/(\n)( *)([^ ].*) *(\r)/',
        'mark_up_poetry_line',
        $s );

    // And mark the whole thing as poetry.
    return "\r\n<lg>$s</lg>\r\n\r\n";
}

function mark_up_poetry_line($m)
{
    $nl     = $m[1];
    $indent = $m[2];
    $words  = $m[3];
    $cr     = $m[4];

    $i = strlen($indent);
    $attr = ( $i > 0 ? " rend='indent($i)'" : "" );
    return "$nl<l$attr>$words</l>$cr";
}

// -----------------------------------------------------------------------------

function page_info_sql( $project, $limit_round_id, $which_text )
{
    $projectid = $project->ProjectId();

    if($limit_round_id == "[OCR]")
    {
        return "SELECT fileid, master_text 
                FROM pages
                WHERE projectid = '$projectid'
                ORDER BY fileid";
    }

    $idx = RoundIndexForId($limit_round_id);

    if($which_text == "EQ")
    {
        return "SELECT 
                    fileid,
                    round{$idx}_text AS pagetext,
                    round{$idx}_user AS pageuser
                    FROM pages
                WHERE projectid = '$projectid'
                ORDER BY fileid";
    }
    else
    {
        $rstr = "";
        for($i = $idx; $i > 0; $i--)
        {
            $rstr = "round{$i}_text,\n";
            $ustr = "round{$i}_user, ' ',\n";
        }
        $rstr .= "master_text";
        $ustr .= "''";

        return "SELECT 
                    fileid,
                    COALESCE($rstr) AS pagetext,
                    TRIM(CONCAT($ustr)) AS pageuser
                FROM pages
                WHERE projectid = '$projectid'
                ORDER BY fileid";
    }
/*
    if ( $limit_round_id == '[OCR]' ) // somewhat kludgey
    {
        // doesn't matter what $which_text is.
        $text_column_expr = 'master_text';
        $user_fields = "";
    }
    else
    {
        $limit_round = get_Round_for_round_id($limit_round_id);
        if ( $which_text == 'EQ' )
        {
            // For each page, fetch the text (if any) saved in the selected round.
            $text_column_expr = $limit_round->text_column_name;
        }
        else if ( $which_text == 'LE' )
        {
            // For each page, fetch the latest text saved in any round up to and
            // including the selected round.
            $text_column_expr = "CASE";
            for ( $rn = $limit_round->round_number; $rn > 0; $rn-- )
            {
                $round = get_Round_for_round_number($rn);
                $text_column_expr .=
                    " WHEN LENGTH({$round->text_column_name}) THEN {$round->text_column_name}";

                // Originally the condition was:
                //    WHEN LENGTH({$round->user_column_name})
                // But the user column is filled in as soon as
                // the page is checked out; but until the user does
                // a save (in progress or done), the text is empty.
                // (So you get a blank page in the output, rather than
                // the text from the previous round.)
                // One fix might be to copy the starting text into the
                // round text when the page is checked out. But there
                // would be repercussions elsewhere.
                //
                // So I changed user_column_name to text_column_name. 
                // We look for the latest non-empty text for the page.
                // The problem is, if the user has intentionally saved
                // an empty text, we'll skip over it. This shouldn't
                // happen -- the text should be '[Blank Page]' or
                // '[Illustration]' -- but (a) mistakes happen, and
                // (b) another DP site might say empty pages are fine.
                // It's possible to distinguish between unsaved and 
                // saved-empty, but the SQL would be complicated,
                // and there's a fair chance I'd get it wrong.
                //
                // I think this is an okay solution for now.
            }
            $text_column_expr .= " ELSE master_text";
            $text_column_expr .= " END";
        }
        else
        {
            die("bad value for which_text: '$which_text'");
        }

        $user_fields = "";
        for ( $rn = 1; $rn <= $limit_round->round_number; $rn++ )
        {
            $round = get_Round_for_round_number($rn);
            $user_fields .= ", {$round->user_column_name}";
        }
    }
*/

}

function page_info_fetch( $res )
// For the next page in the query-result,
// return an array consisting of (in order):
// -- the page text resulting from the page-editing rounds;
// -- the filename of the page image;
// -- an array of the usernames of the users who worked on the page in the rounds.
// If there's no next page, return FALSE;
{
    $a = mysql_fetch_row($res);
    if (!$a) return FALSE;

    $text_data = $a[0];
    $filename  = $a[1];
    $proofer_names = array_slice( $a, 2 );

    return array(
        $text_data,
        $filename,
        $proofer_names
    );
}

// vim: sw=4 ts=4 expandtab
?>
